#include "linux/of.h"
#include "linux/types.h"
#include "asm/ptrace.h"
#include "linux/errno.h"
#include "linux/irq.h"
#include "linux/irqdesc.h"
#include "linux/radix-tree.h"
#include "internals.h"

void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
{
	//print_irq_desc(irq, desc);
	//kstat_incr_irqs_this_cpu(irq, desc);
	//ack_bad_irq(irq);
}

irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags)
{
	irqreturn_t retval = IRQ_NONE;
	unsigned int irq = desc->irq_data.irq;
	struct irqaction *action;

	for_each_action_of_desc(desc, action)
	{
		irqreturn_t res;

		//trace_irq_handler_entry(irq, action);
		res = action->handler(irq, action->dev_id);
		//trace_irq_handler_exit(irq, action, res);

		//if (WARN_ONCE(!irqs_disabled(), "irq %u handler %pF enabled interrupts\n", irq, action->handler))
			//local_irq_disable();

		switch (res)
		{
		case IRQ_WAKE_THREAD:
			if (!action->thread_fn)
			{
				//warn_no_thread(irq, action);
				break;
			}

			//__irq_wake_thread(desc, action);
		case IRQ_HANDLED:
			*flags |= action->flags;
			break;

		default:
			break;
		}

		retval |= res;
	}

	return retval;
}

irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
{
	irqreturn_t retval;
	unsigned int flags = 0;

	retval = __handle_irq_event_percpu(desc, &flags);

	return retval;
}

irqreturn_t handle_irq_event(struct irq_desc *desc)
{
	irqreturn_t ret;

	desc->istate &= ~IRQS_PENDING;
	irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
	//raw_spin_unlock(&desc->lock);

	ret = handle_irq_event_percpu(desc);

	//raw_spin_lock(&desc->lock);
	irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
	return ret;
}